package com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.module;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.CommonAttrVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ModuleVO;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.LockOrReleaseInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneNewOfferSeneVO;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.service.util.CopyToDtoUtil;
import com.iwhalecloud.bss.kite.web.service.accept.attr.handler.ICommonAttrHandler;
import com.iwhalecloud.bss.kite.web.service.accept.bo.AcceptContext;
import com.iwhalecloud.bss.kite.web.service.accept.bo.SceneModule;
import com.iwhalecloud.bss.kite.web.service.accept.handler.module.AbstractModuleHandler;
import com.iwhalecloud.bss.kite.web.service.accept.util.HandlerFactoryUtils;
import com.ztesoft.bss.base.entity.StaticAttrDO;
import com.ztesoft.bss.common.util.SpringUtil;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class LockOrReleaseInfoModuleHandler extends AbstractModuleHandler {

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Override
    public List<? extends ModuleVO> execute(AcceptContext context, SceneModule sceneModule) {
        LockOrReleaseInfoVO lockOrReleaseInfoVO = new LockOrReleaseInfoVO();
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        List<CommonAttrVO> commonAttrList = new ArrayList<>();
        String sceneInstId = context.getAcceptRequest().getSceneInstId();
        // 1-根据moduleId和商品分类objId查询commonAttrs
        commonAttrList = listCommonAttrByModuleId(context, sceneModule, commonAttrList, sceneInstId);
        // 对公共属性根据orderId进行排序
        commonAttrList.sort(Comparator.comparing(commonAttrVO -> NumberUtils.toInt(commonAttrVO.getOrderId(), 0)));
        // 2-初始化公共属性
        // 订购和资源核查都需要初始化公共属性
        if (KiteListUtils.isNotEmpty(commonAttrList)) {
            initCommonAttr(sceneInstId, commonAttrList);
        }
        List<KiteAttr> commonAttrList2 = querySceneInstService.listCommonAttrsByModuleId(context.getAcceptRequest().getSceneInstId(), "143");
        if (KiteListUtils.isNotEmpty(commonAttrList2)) {
            commonAttrList2.removeIf(
                commonAttr -> !KiteStringUtils.equalsAny(commonAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M));
            List<InstAttrDTO> instAttrDTOList = CopyToDtoUtil.transInstAttrDtoList(commonAttrList2);
            // 信息返回空，不展示
            if (KiteListUtils.isEmpty(instAttrDTOList)) {
                return Lists.newArrayList();
            }
            lockOrReleaseInfoVO.setLockOrReleaseAttr(instAttrDTOList);
            SceneNewOfferSeneVO sceneInfoVo = (SceneNewOfferSeneVO) context.getSceneVo();
            sceneInfoVo.setLockOrReleaseInfoVO(lockOrReleaseInfoVO);
        }
        return Collections.singletonList(lockOrReleaseInfoVO);
    }

    @Override
    public List<ModuleVO> previewSceneVo(AcceptContext context, SceneModule sceneModule) {
        LockOrReleaseInfoVO lockOrReleaseInfoVO = new LockOrReleaseInfoVO();
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        List<KiteAttr> commonAttrList = querySceneInstService.listCommonAttrsByModuleId(context.getAcceptRequest().getSceneInstId(), "143");
        if (KiteListUtils.isNotEmpty(commonAttrList)) {
            //设置预览模式
            commonAttrList.forEach((attr) -> {
                attr.setAttrValueTypeId("TT");
            });
            List<InstAttrDTO> instAttrDTOList = CopyToDtoUtil.transInstAttrDtoList(commonAttrList);
            // 信息返回空，不展示
            if (KiteListUtils.isEmpty(instAttrDTOList)) {
                return Lists.newArrayList();
            }
            lockOrReleaseInfoVO.setLockOrReleaseAttr(instAttrDTOList);
            SceneNewOfferSeneVO sceneInfoVo = (SceneNewOfferSeneVO) context.getSceneVo();
            sceneInfoVo.setLockOrReleaseInfoVO(lockOrReleaseInfoVO);
        }
        return Collections.singletonList(lockOrReleaseInfoVO);
    }

    private List<CommonAttrVO> listCommonAttrByModuleId(AcceptContext context, SceneModule sceneModule,
                                                        List<CommonAttrVO> commonAttrList, String sceneInstId) {
        Assert.notNull(context, "context must not be null");
        Assert.notNull(sceneModule, "sceneModule must not be null");
        Assert.notNull(sceneModule.getKiteModule(), "kiteModule must not be null");
        Assert.notNull(context.getAcceptRequest(), "acceptRequest must not be null");
        Assert.hasText(context.getAcceptRequest().getSceneInstId(), "sceneInstId must not be empty");
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        String moduleId = sceneModule.getKiteModule().getModuleId();
        // 获取产品分类id
        String offerId = context.getAcceptRequest().getOfferId();
        String objId = OfferCache.get(offerId).getAttrValue("cateId");
        List<KiteAttr> commonAttrsByObjId = querySceneInstService
            .listCommonAttrsByObjIdAndModuleId(sceneInstId, objId, moduleId);
        List<KiteAttr> commonAttrs = querySceneInstService
            .listCommonAttrsByObjIdAndModuleId(sceneInstId, null, moduleId);
        if (KiteListUtils.isNotEmpty(commonAttrsByObjId)) {
            commonAttrs.addAll(commonAttrsByObjId);
        }
        List<InstAttrDTO> instAttrDTOList = CopyToDtoUtil.transInstAttrDtoList(commonAttrs);
        if (KiteListUtils.isNotEmpty(instAttrDTOList)) {
            commonAttrList = KiteListUtils.isNotEmpty(instAttrDTOList) ?
                instAttrDTOList.stream().map(attrDTO -> KiteBeanUtils.transform(attrDTO, CommonAttrVO.class))
                    .collect(Collectors.toList()) :
                Collections.emptyList();
            if (KiteListUtils.isNotEmpty(commonAttrList)) {
                commonAttrList.stream().forEach(commonAttrVO -> {
                    String defaultValue = commonAttrVO.getDefaultValue();
                    if (!KiteStringUtils.isEmpty(defaultValue) && KiteStringUtils.isEmpty(commonAttrVO.getValue())) {
                        if (KeyConsts.DROPDOWN.equals(commonAttrVO.getAttrValueTypeId())) {
                            List<StaticAttrDO> attrDos = commonAttrVO.getAttrValues();
                            attrDos.stream().forEach(attrDo -> {
                                String attrvalue = attrDo.getAttrValue();
                                if (KiteStringUtils.isEqual(attrvalue, defaultValue)) {
                                    commonAttrVO.setValue(defaultValue);
                                    commonAttrVO.setValueDesc(attrDo.getAttrValueDesc());
                                }
                            });
                        } else {
                            commonAttrVO.setValue(defaultValue);
                        }
                    }
                    // 变更业务如果返回代理人信息，进入录入界面时默认展示
                    if (KiteStringUtils.isEmpty(defaultValue) && KiteStringUtils.isEmpty(commonAttrVO.getValue())
                        && (KiteStringUtils.equals("AgentInfo", commonAttrVO.getFieldName()) || KiteStringUtils.equals("HandlerCustInfo", commonAttrVO.getFieldName()))) {
                        String channelId = querySceneInstService.getExtParameterValue(sceneInstId, "channelId");
                        String handlerInfoName = querySceneInstService.getExtParameterValue(sceneInstId, "handler_info_name");
                        if (KiteStringUtils.isNotEmpty(channelId) && KiteStringUtils.equals("AgentInfo", commonAttrVO.getFieldName())) {
                            commonAttrVO.setValue("T");
                        }
                        if (KiteStringUtils.isNotEmpty(handlerInfoName) && KiteStringUtils.equals("HandlerCustInfo", commonAttrVO.getFieldName())) {
                            commonAttrVO.setValue("T");
                        }
                    }
                });
            }
        }
        return commonAttrList;
    }

    /**
     * 初始化公共属性
     *
     * @param sceneInstId
     * @param commonAttrList
     */
    @Transactional(rollbackFor = Exception.class)
    public void initCommonAttr(String sceneInstId, List<CommonAttrVO> commonAttrList) {
        String afCommonAttrInit = querySceneInstService.getExtParameterValue(sceneInstId, "afCommonAttrInit");
        for (int i = 0; i < commonAttrList.size(); i++) {
            CommonAttrVO commonAttrVO = commonAttrList.get(i);
            if (KiteStringUtils.isNotBlank(commonAttrVO.getHandlerClass())) {
                ICommonAttrHandler commonAttrHandler = HandlerFactoryUtils
                    .getHandler(commonAttrVO.getHandlerClass());
                if (commonAttrHandler != null) {
                    if (!"T".equals(afCommonAttrInit)) {
                        commonAttrHandler.init(commonAttrVO);
                    }
                    commonAttrHandler.apply(sceneInstId, commonAttrVO.getFieldName(), commonAttrVO.getValue(),
                        commonAttrVO.getValueDesc());
                }
            } else {
                operateSceneInstService
                    .setCommonAttrValue(sceneInstId, commonAttrVO.getFieldName(), commonAttrVO.getValue(),
                        commonAttrVO.getValueDesc());
            }
        }
    }
}
